package com.googlecode.sparda.experiments;

import org.junit.Ignore;

@Ignore
public final class MaxStackTraceElementReturn {

	public static void main(String[] args) {
		System.out.println("Getting deep");
		int recursiveMaxDeep = getRecursiveMaxDeep();
		
		System.out.println("Getting StackOverflowError -> StackTrace");
		StackTraceElement[] stackTraceElements_Exception_GetStackTrace = getStackOverFlowForRecursiveMaxDeep().getStackTrace();
		int stackDeep_Exception_GetStackTrace = stackTraceElements_Exception_GetStackTrace.length;
		
		StackTraceElement[] stackTraceElementsCurrentThread = getStackTraceElementForRecursiveMaxDeep();
		int stackDeep_CurrentThread = stackTraceElementsCurrentThread.length;
		
		System.out.println();
		System.out.println("Summary:");
		System.out.printf("\tRecursive Deep is ~ %d\n", recursiveMaxDeep);
		System.out.printf("\tStackTraceElements getting for Exception is ~ %d\n", stackDeep_Exception_GetStackTrace);
		System.out.printf("\tStackTraceElements getting for CurrentThread is ~ %d\n", stackDeep_CurrentThread);
		System.out.printf("\tStack Trace Omitted for Exception ~ %d StackTraceElement\n", Math.max(0, recursiveMaxDeep - stackDeep_Exception_GetStackTrace));
		System.out.printf("\tStack Trace Omitted for CurrentThread ~ %d StackTraceElement\n", Math.max(0, recursiveMaxDeep - stackDeep_CurrentThread));
		System.out.println();
		if(stackDeep_CurrentThread == stackDeep_Exception_GetStackTrace)
			System.out.println("\tStack Trace of CurrentThread and Exception_GetStackTrace are equals");
		else if(stackDeep_CurrentThread > stackDeep_Exception_GetStackTrace)
			System.out.println("\tStack Trace of CurrentThread is greater than Exception_GetStackTrace");
		else //if(stackDeep_CurrentThread < stackDeep_Exception_GetStackTrace)
			System.out.println("\tStack Trace of Exception_GetStackTrace is greater than CurrentThread");
	}
	
	private static int getRecursiveMaxDeep() {
		return getRecursiveMaxDeep(1); 
	}

	private static int getRecursiveMaxDeep(final int currentDeep) {
		try {
			return getRecursiveMaxDeep(currentDeep + 1);
		} catch (StackOverflowError e) {
			return currentDeep;
		} 
	}
	
	private static StackOverflowError getStackOverFlowForRecursiveMaxDeep() {
		return getStackOverFlowForRecursiveMaxDeep(1);
	}
	
	private static StackOverflowError getStackOverFlowForRecursiveMaxDeep(final int currentDeep) {
		try {
			return getStackOverFlowForRecursiveMaxDeep(currentDeep + 1);
		} catch (StackOverflowError e) {
			return e;
		}
	}
	
	private static StackTraceElement[] getStackTraceElementForRecursiveMaxDeep() {
		return getStackTraceElementForRecursiveMaxDeep(1);
	}
	
	private static StackTraceElement[] getStackTraceElementForRecursiveMaxDeep(final int currentDeep) {
		try {
			return getStackTraceElementForRecursiveMaxDeep(currentDeep + 1);
		} catch (StackOverflowError e) {
			return Thread.currentThread().getStackTrace();
		}
	}

}
